.text
.global _start, _undef, _swi, _pabort, _dabort, _irq, _fiq

// 2nboot程序设置了栈底，初始值0xFFFF8000

_start:                     // 地址 0x42C00000
    bl init_all             // 初始化
    @ .word 0xFFFF0000
    @ swi 0x123
    mov sp, #0x50000000      // 设置栈底
    @ bl log_all
    b main
    b .


_undef:
    stmdb sp!, {r0-r12, lr}             // 保存现场，lr存的是产生undef异常的指令的下一条指令地址；
    sub r0, lr, #4
    bl except_und
    b .
    ldmia sp!, {r0-r12, pc}^            // 恢复现场，'^'表示恢复CPSR；

_swi:
    stmdb sp!, {r0-r12, lr}
    sub r0, lr, #4
    bl except_swi
    ldmia sp!, {r0-r12, pc}^

_pabort:
    sub	lr, lr, #4
    stmdb sp!, {r0-r12, lr}
    mov r0, lr
    bl except_pabort
    b .
    ldmia sp!, {r0-r12, pc}^

_dabort:
    sub	lr, lr, #8
    stmdb sp!, {r0-r12, lr}
    ldmia sp!, {r0-r12, lr}
    mov r0, lr
    bl except_dabort
    b .
    ldmia sp!, {r0-r12, pc}^
    

_irq:
    sub	lr, lr, #4
    @ stmdb sp!, {r0-r12, lr}
    @ STMFD   sp!, lr                                 // lr: 当前线程的下一次pc
    
    STR     lr, [sp, #-8]
    @ STMFD   sp!, {r0, r1}
    STR     r1, [sp, #-12]
    STR     r0, [sp, #-16]
    MRS     r1, spsr
    STR     r1, [sp, #-4]

    mov     r0, sp

    MRS     r1, spsr                                // 在A9中，通过修改模式来读取线程栈指针
    ORR     r1, r1, #0x80                            // I位置1
    MSR     cpsr, r1                                // 修改模式

    @ STMFD   sp!, {R0-R3, R12, LR, PC}             @ 进入中断时，保存这几个寄存器, 要保存fp, fp会被其他中断改变
    
    LDR     r1, [r0, #-8]                            // 取pc值
    STMFD   sp!, {r1}
    STMFD   sp!, {r2, r3, r12, lr}
    ADD     r2, r0, #-16
    LDMFD   r2!, {r0, r1}
    STMFD   sp!, {r0, r1}
    LDR     r0, [r2, #4]                              // 取cpsr值
    STMFD   sp!, {r0}                                 // 存放在栈顶


    @ 开始进入中断服务

    mov	r3, #8192
    movt	r3, #49152
    ldr	r3, [r3]
    cmp	r3, #0
    beq	_vicirqstatus_ch1
    mov	r3, #12032
    movt	r3, #49152
    ldr	r3, [r3]
    blx	r3
    mov	r3, #12032
    movt	r3, #49152
    mov	r2, #0
    str	r2, [r3]
    b	_end
_vicirqstatus_ch1:
    mov	r3, #12288
    movt	r3, #49152
    ldr	r3, [r3]
    cmp	r3, #0
    beq	_end
    mov	r3, #16128
    movt	r3, #49152
    ldr	r3, [r3]
    blx	r3
    mov	r3, #16128
    movt	r3, #49152
    mov	r2, #0
    str	r2, [r3]
_end:

    @ 结束进入中断服务


    LDMFD   sp!, {r0}                   @ cpsr值
    MSR     spsr, r0

    LDMFD   sp!, {R0-R3, R12, LR, PC}^  @ 加载到xPSR，PC（任务入口地址），R14，R12，R3，R2，R1，R0（任务的形参）


_fiq:
    b .
